home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 3 / Amiga Tools 3.iso / grafik / raytracing / rayshade-4.0.6.3 / libray / libtext / texture.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-09  |  5.0 KB  |  219 lines

  1. /*
  2.  * texture.c
  3.  *
  4.  * Copyright (C) 1989, 1991, Craig E. Kolb
  5.  * All rights reserved.
  6.  *
  7.  * This software may be freely copied, modified, and redistributed
  8.  * provided that this copyright notice is preserved on all copies.
  9.  *
  10.  * You may not distribute this software, in whole or in part, as part of
  11.  * any commercial product without the express consent of the authors.
  12.  *
  13.  * There is no warranty or other guarantee of fitness of this software
  14.  * for any purpose.  It is provided solely "as is".
  15.  *
  16.  * texture.c,v 4.1 1994/08/09 08:03:27 explorer Exp
  17.  *
  18.  * texture.c,v
  19.  * Revision 4.1  1994/08/09  08:03:27  explorer
  20.  * Bump version to 4.1
  21.  *
  22.  * Revision 1.1.1.1  1994/08/08  04:52:15  explorer
  23.  * Initial import.  This is a prerelease of 4.0.6enh3, or 4.1 possibly.
  24.  *
  25.  * Revision 4.0  91/07/17  14:44:11  kolb
  26.  * Initial version.
  27.  * 
  28.  */
  29. #include "texture.h"
  30.  
  31. /*
  32.  * Transformation structures used to map from texture space to
  33.  * model/primitive/world space.
  34.  */
  35. Trans prim2model, model2text, prim2text, world2text;
  36.  
  37. #define ApplyMapping(m,o,p,n,c,u,v)    (*m->method)(m, o, p, n, c, u, v)
  38.  
  39. Texture *
  40. TextCreate(data, meth)
  41. TextRef data;
  42. void (*meth)();
  43. {
  44.     Texture *res;
  45.  
  46.     res = (Texture *)share_calloc(1, sizeof(Texture));
  47.     res->data = data;
  48.     res->method = meth;
  49.     res->trans = (Trans *)NULL; 
  50.     res->next = (Texture *)NULL;
  51.     res->animtrans = FALSE;
  52.     return res;
  53. }
  54.  
  55. /*
  56.  * Apply appropriate textures to a surface.
  57.  */
  58. void
  59. TextApply(tlist, prim, ray, pos, norm, gnorm, surf, p2model, world2model)
  60. Texture *tlist;                /* Textures */
  61. Geom *prim;
  62. Ray *ray;
  63. Vector *pos, *norm, *gnorm;        /* pos, shading norm, geo. norm */
  64. Surface *surf;
  65. Trans *p2model, *world2model;
  66. {
  67.     Vector ptmp;
  68.     Texture *ttmp;
  69.  
  70.     prim2model = *p2model;
  71.     /*
  72.      * Walk down texture list, applying each in turn.
  73.      */
  74.     for (ttmp = tlist; ttmp; ttmp = ttmp->next) {
  75.         /*
  76.          * Make copies of pos & ray to pass to the texturing function.
  77.          */
  78.         ptmp = *pos;
  79.         if (ttmp->trans) {
  80.             /*
  81.              * 'take' the inverse of ttmp->trans, since
  82.              * transforming a texture means applying the
  83.              * inverse of the transformation
  84.              * to the point of intersection, etc.
  85.              */
  86.             if (ttmp->animtrans) {
  87.                 /*
  88.                  * Resolve animated associations.
  89.                  * We currently do not store a time
  90.                  * for the texture, so we can't know if
  91.                  * we're already resolved for the current
  92.                  * ray->time.
  93.                  */
  94.                 TransResolveAssoc(ttmp->trans);
  95.                 TransComposeList(ttmp->trans, &model2text);
  96.                 TransInvert(&model2text, &model2text);
  97.             } else
  98.                 TransInvert(ttmp->trans, &model2text);
  99.             /*
  100.              * We compose ttmp->trans, which maps from model to
  101.              * texture space, with prim2model and world2model
  102.              * to get prim2text and world2text.
  103.              */
  104.             TransCompose(&model2text, &prim2model, &prim2text);
  105.             TransCompose(&model2text, world2model, &world2text);
  106.             /*
  107.              * Transform intersection point to texture space.
  108.              * Ray and normal are passed in model space.
  109.              */
  110.             ModelPointToText(&ptmp);
  111.         } else {
  112.             /*
  113.               * By default, texture and model space are identical.
  114.               */
  115.             TransInit(&model2text);
  116.             TransCopy(&prim2model, &prim2text);
  117.             TransCopy(world2model, &world2text);
  118.         }
  119.  
  120.         /*
  121.          * Call texture function.
  122.          */
  123.         (*ttmp->method) (ttmp->data,prim,ray,&ptmp,norm,gnorm,surf);
  124.     }
  125. }
  126.  
  127. /*
  128.  * Compute UV at 'pos' on given primitive.
  129.  */
  130. TextToUV(mapping, prim, pos, norm, u, v, dpdu, dpdv)
  131. Mapping *mapping;
  132. Geom *prim;
  133. Vector *pos, *norm, *dpdu, *dpdv;
  134. Float *u, *v;
  135. {
  136.     Vec2d uv;
  137.     Vector ptmp;
  138.     RSMatrix t;
  139.  
  140.     ptmp = *pos;
  141.  
  142.     if (mapping->flags & PRIMSPACE) {
  143.         /*
  144.           * Convert point and normal to primitive space.
  145.           */
  146.         TextPointToPrim(&ptmp);
  147.     } else {
  148.         /*
  149.          * Convert point and normal to object space.
  150.          */
  151.         TextPointToModel(&ptmp);
  152.     }
  153.  
  154.     ApplyMapping(mapping, prim, &ptmp, norm, &uv, dpdu, dpdv);
  155.  
  156.     /*
  157.      * Transform UV by model2text.  We set X = u and Y = v,
  158.      * while Z = 0.
  159.      * Although the UV coordinates may be in prim space,
  160.      * we treat them as if they are model-space coords.
  161.      * This is due to the fact that we want the texture
  162.      * to be applied in model space.
  163.      */
  164.     ptmp.x = uv.u;
  165.     ptmp.y = uv.v;
  166.     ptmp.z = 0.;
  167.     PointTransform(&ptmp, &model2text.trans);
  168.     *u = ptmp.x;
  169.     *v = ptmp.y;
  170.     if (dpdu == (Vector *)NULL || dpdv == (Vector *)NULL)
  171.         return;
  172.     /*
  173.      * Here's the ugly part.
  174.      * Build initial UVN-->XYZ matrix...
  175.      */
  176.     ArbitraryMatrix(dpdu->x, dpdu->y, dpdu->z,
  177.              dpdv->x, dpdv->y, dpdv->z,
  178.              norm->x, norm->y, norm->z, 0., 0., 0., &t);
  179.     /*
  180.      * ...transform to model space...
  181.      */
  182.     MatrixMult(&t, &prim2model.trans, &t);
  183.     /*
  184.      * ... apply model2text in UVN space.
  185.      */
  186.     MatrixMult(&model2text.itrans, &t, &t);
  187.     dpdu->x = t.matrix[0][0];
  188.     dpdu->y = t.matrix[0][1];
  189.     dpdu->z = t.matrix[0][2];
  190.     dpdv->x = t.matrix[1][0];
  191.     dpdv->y = t.matrix[1][1];
  192.     dpdv->z = t.matrix[1][2];
  193.     (void)VecNormalize(dpdu);
  194.     (void)VecNormalize(dpdv);
  195. }
  196.  
  197. /*
  198.  * Append 'text' to the given linked list of textures.
  199.  * Note that 'text' may be a list, too.
  200.  */
  201. Texture *
  202. TextAppend(text, list)
  203. Texture *text, *list;
  204. {
  205.     Texture *tp;
  206.  
  207.     if (list) {
  208.         /*
  209.          * Walk to the end of the list
  210.          */
  211.         for (tp = list;tp->next ;tp = tp->next)
  212.                 ;
  213.         tp->next = text;
  214.         return list;
  215.     }
  216.     /* else */
  217.     return text;
  218. }
  219.